נניח שמישהו לחץ כמה פעמים על קישור או לחץ אנטר בשורת הכתובת כמה פעמים, והספיקו להישלח כמה בקשות לסקריפט PHP. (זה יכול לקרות, נכון?)

דבר כזה יכול להרוס את הסקריפט בהנחה שהוא נעצר ברגע שהדפדפן עושה abort.

אני אתן דוגמה לדבר שיכול להיהרס. נניח שבכל בקשה אני בודק אם מוגדר ערך א' בסשן, ואם לא, אני מבצע את השלבים הבאים:
1. מעדכן ערך א' בסשן
2. מעדכן ערך ב' בסשן
3. מעדכן ערך ג' בסשן

עכשיו מישהו בא ושלח כמה בקשות. הסקריפט הראשון הפסיק לרוץ מיד אחרי שלב 1. עכשיו הבקשות הבאות יהיו שבורות, כי שלבים 2 ו-3 לא יקרו (במקרה הזה עד שהסשן ייגמר).

2 תשובות

avatar ענה OrelBeY ב 02 לאוגוסט 2014 #

PHP לא תזהה שמשתמש ביטל את החיבור עד שיהיה ניסיון לשלוח פלט למשתמש. אם אתה משתמש ב-MVC כמו שצריך (או אפילו סתם משתמש ב-buffer), שליחת פלט למשתמש תיעשה אצלך פעם אחת - לקראת סוף הסקריפט שלך. כן יכול להיות שיש דברים אחרים אחרי זה, אבל הם כבר לא יקרו, ועם בקשה נוספת - הם יקרו. (לא בכל מצב אמנם.)

בכל מקרה, קיימת הגדרת תצורה ב-PHP בשם ignore_user_abort. כשהיא מוגדרת ל-true, הסקריפט לא יסתיים בעקבות ביטול חיבור מצד המשתמש.

זה ניסיון שלי לענות על השאלה. אם יש לך משהו להוסיף או אם אמרתי משהו לא נכון או לא מדויק - כמו בכל מקרה אחר, אנא הגיבו.

avatar ענה intval ב 03 לאוגוסט 2014 #

אפשר רק להוסיף שבכל ארכיטקטורה קצת יותר מודרנית מ wamp (קצת יותר מודרנית מ apache + mod_php) השרת שמקבל את הבקשות בכלל לא מחובר אל PHP. לרוב לפני שבקשה מגיע אל PHP היא עוברת בדרך כמה load balancerים או לפחות שרת פרונטנד אחד שלא עושה שום דבר בעצמו אלא מהעביר את החיבור הלאה.
כאן באתר למשל יש שרת nginx שמקבל את הבקשות ומעביר אותם ל php fpm daemon. אם הבקשה הגיע לשם - היא תתבצע, לא משנה איפה באותו רגע המשתמש ומהמצב של החיבור בינו לבין nginx.